package com.sy.service;

import com.sy.dto.RedPacketDto;
import com.sy.util.RedPacketUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class RedPacketServiceImpl implements IRedPacketService {
    private static final String KEYPREFIX="redis:red:packet:";
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IRedService service;

    private static final Logger logger= LoggerFactory.getLogger(RedPacketServiceImpl.class);

    @Override
    public String handOut(RedPacketDto dto) throws Exception {
        String redId="";
        if(dto.getAmount()>0 && dto.getTotal()>0){
            //取出红包随机金额
            List<Integer> list=RedPacketUtil.dividedRedPackage(dto.getAmount(),dto.getTotal());
            //生成红包唯一标识
            String uuid= UUID.randomUUID().toString();
            StringBuilder sb=new StringBuilder(KEYPREFIX).append(dto.getUserId()).append(":").append(uuid.replace("-",""));
            redId=sb.toString().trim();
            //将随机金额存入缓存list中
            redisTemplate.opsForList().leftPushAll(redId,list.toArray());
            setTime(redId);
            //根据缓存的key的前缀与其他信息拼接成一个新的用户存储红包总数的key
//            String totalId=new StringBuilder(redId).append(":total").toString();

//            redisTemplate.opsForValue().set(totalId,dto.getTotal());
//            setTime(totalId);
            //异步存取红包进入mysql
            service.recordRedPacket(dto,redId,list);

        }else{
            logger.error("系统异常-分发红包-参数不合法");
            throw new Exception("系统异常-分发红包-参数不合法");
        }
        return redId;
    }

    @Override
    public BigDecimal rob(Integer userId, String redId) throws Exception {
        ValueOperations vo=redisTemplate.opsForValue();
        Object obj=vo.get(redId+userId+":rob");
        if(obj!=null){
            return new BigDecimal(obj.toString());
        }
        if(click(redId)){
            String lockKey=redId+userId+"-lock";
            //相当于setnx命令
            boolean lock=vo.setIfAbsent(lockKey,redId);
            //设置锁过期时间
            setTime(lockKey);
            if(lock){
                ListOperations lo=redisTemplate.opsForList();
                Object value=lo.rightPop(redId);
                if(value!=null){//已经发布红包了

                    //开始抢红包 变成元
                    BigDecimal money=new BigDecimal(value.toString()).divide(new BigDecimal(100));
                    //生成抢红包的缓存
                    service.recordRobRedPacket(userId,redId,new BigDecimal(value.toString()));
                    vo.set(redId+userId+":rob",money);

                    logger.info("当前用户抢到红包：userId={} key={} 金额={}",userId,redId,money);
                    return money;
                }
            }
        }
        return null;
    }

    private boolean click(String redId) {//当前红包下 判断是否抢完
        ListOperations lo=redisTemplate.opsForList();
        Object total=lo.size(redId);
        if(total!=null && Integer.parseInt(total.toString())>0){
            return true;
        }
        return false;
    }

    private void setTime(String key){
        redisTemplate.expire(key,24,TimeUnit.HOURS);
    }
}
